/*
 * MIT License
 *
 * Copyright (c) 2023 芊芊墨客
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

package com.zhangmeng.tools.controller;

import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.io.resource.Resource;
import com.leewyatt.rxcontrols.controls.RXMediaProgressBar;
import com.zhangmeng.tools.utils.*;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.Duration;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Properties;
import java.util.Random;

/**
 * @author : 芊芊墨客
 * @version : 1.0
 * @date : 2023-02-16 11:08
 */
@Slf4j
public class VideoController {

    private static ObservableList<File> dirs = FXCollections.observableArrayList();
    private static ObservableList<Media> medias = FXCollections.observableArrayList();
    private static ObservableList<File> files = FXCollections.observableArrayList();
    private MediaPlayer mp;

    public MediaPlayer getMp() {
        return mp;
    }

    private final SimpleBooleanProperty isplaying = new SimpleBooleanProperty(false);
    private final SimpleIntegerProperty playindex = new SimpleIntegerProperty(1);
    private final SimpleDoubleProperty playprogress = new SimpleDoubleProperty(0.0D);
    private StringBuffer sb;
    private final Random ran = new Random();

    private HBox hbox;

    private static final double gap = 5.0D;
    private final int number = SpectrumUtils.CELL_NUMBER;
    private ObservableList<SimpleFloatProperty> height;
    private final double width = SpectrumUtils.CELL_WIDTH;

    private double sl_vol_num = 0.30;

    public ObservableList<SimpleFloatProperty> getHeight() {
        return height;
    }

    public void setHeight(ObservableList<SimpleFloatProperty> height) {
        this.height = height;
    }

    public SimpleDoubleProperty root_width = new SimpleDoubleProperty(1080);
    public SimpleDoubleProperty root_height = new SimpleDoubleProperty(649);

    /**
     * 设置图标
     */
    @FXML
    private ImageView iv_set;

    /**
     * 重复
     */
    @FXML
    private ImageView iv_cycle;

    /**
     * 上一首
     */
    @FXML
    private ImageView iv_last;

    /**
     * 播放
     */
    @FXML
    private ImageView iv_play;

    /**
     * 下一首
     */
    @FXML
    private ImageView iv_next;

    /**
     * 列表
     */
    @FXML
    private ImageView iv_list;

    /**
     * 音量
     */
    @FXML
    private ImageView iv_vol;

    /**
     * 音量刻度
     */
    @FXML
    private Slider sl_vol;

    /**
     * 循环类型
     */
    private final SimpleIntegerProperty cycletype = new SimpleIntegerProperty(0);

    @FXML
    private ListView listView;

    @FXML
    private Label label_name;

    @FXML
    private Label label_time;

    @FXML
    private RXMediaProgressBar progressBar;

    private static final String LRC_CODE = "utf-8";

    @FXML
    private MediaView mv;

    @FXML
    private AnchorPane video_root;

    @FXML
    private HBox mv_hbox;

    public void full_screen() {

        AnchorPane root = null;
        try {
            root = FXMLLoader.load(ResourcesUtils.getResource("video-player"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        mv = (MediaView) root.lookup("#mv");
        mv.setMediaPlayer(this.mp);

        Stage stage = (Stage) this.progressBar.getScene().getWindow();
        stage.hide();

        Scene scene = new Scene(root);
        Stage player_stage = new Stage();
        player_stage.setScene(scene);
        player_stage.setTitle("播放");
        player_stage.setWidth(1600);
        player_stage.setHeight(800);
        player_stage.setFullScreen(true);
        player_stage.setOnCloseRequest(windowEvent -> {
            log.info("播放关闭");
            stage.show();
        });
        player_stage.show();
    }

    @FXML
    public void initialize() {

        files = getMusicFiles();
        initListView();
        medias = getMusicMedias();

        medias.addListener((ListChangeListener<Media>) c -> {
            while (c.next()) {
                if (c.wasAdded()) {
                    if ((medias.size() - 1) >= VideoController.this.playindex.get()) {
                        VideoController.this.mp = new MediaPlayer(medias.get(VideoController.this.playindex.get()));
                    }
                }
                if (medias.size() == 0) {
                    VideoController.this.isplaying.set(false);
                    VideoController.this.mp.pause();
                    VideoController.this.mp = null;
                }
            }
        });

        if (medias.size() == 0) {
            this.mp = null;
            this.sb = new StringBuffer("");
        } else {
            this.mp = new MediaPlayer(medias.get(this.playindex.get()));
            //加载歌词
            this.sb = new StringBuffer(files.get(this.playindex.get()).getName());
            this.sb = new StringBuffer(this.sb.substring(0, this.sb.length() - 4));
            this.mp.setVolume(sl_vol_num);
            this.mv.setMediaPlayer(mp);
        }

        this.playindex.addListener((observable, oldValue, newValue) -> VideoController.this.myPlay());
        this.mv.setPreserveRatio(false);
        this.mv.fitWidthProperty().bind(video_root.prefWidthProperty().subtract(300));
        this.mv.fitHeightProperty().bind(video_root.prefHeightProperty().subtract(130));

        //设置按钮
        set_button();

        //播放器重复按钮
        cycle_button();

        //上一首按钮
        last_button();

        //播放按钮
        play_button();

        //下一首
        next_button();

        //播放列表
        music_list_button();

        //静音按钮
        vol_mute_button();

        //音量
        sl_vol_button();

        initSt();
    }

    public void initSt() {
        this.hbox = new HBox(gap);
        this.hbox.setScaleY(-1.0D);
        this.height = FXCollections.observableArrayList();
        for (int i = 0; i < this.number; ++i) {
            this.height.add(new SimpleFloatProperty(0.0F));
            Color color = ColorUtils.random_color();
//            Color color = Color.DEEPSKYBLUE;
            Rectangle rec = new Rectangle(this.width, 0.0D, color);
            rec.setOpacity(0.6D);
            rec.heightProperty().bind(this.height.get(i));
            this.hbox.getChildren().add(rec);
        }
    }

    public void music_list_button() {

        Image list_white = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_WHITE_LIST));
        Image list_black = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_BLACK_LIST));

        this.iv_list = new ImageView(list_white);
        this.iv_list.hoverProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue) {
                VideoController.this.iv_list.setImage(list_black);
            }

            if (!newValue) {
                VideoController.this.iv_list.setImage(list_white);
            }
        });
    }

    /**
     * 底部设置按钮
     */
    public void set_button() {
        Image set_white = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_WHITE_SET));
        Image set_black = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_BLACK_SET));

        this.iv_set.hoverProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue) {
                VideoController.this.iv_set.setImage(set_black);
            }
            if (!newValue) {
                VideoController.this.iv_set.setImage(set_white);
            }
        });

        this.iv_set.setOnMouseClicked(event -> {
            if (event.getClickCount() == 1 && event.getButton() == MouseButton.PRIMARY) {
                AnchorPane root = null;
                try {
                    root = FXMLLoader.load(ResourcesUtils.getResource("video-set"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Stage primaryStage = (Stage) VideoController.this.listView.getScene().getWindow();
                AlertUtils.alert("设置", root, primaryStage);
            }
        });
    }


    /**
     * 播放器底部 重复按钮
     */
    public void cycle_button() {

        Image cycle_icon_white = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_WHITE_REPEAT));
        Image cycle_icon_black = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_BLACK_REPEAT));
        Image ICON_WHITE_RANDOM = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_WHITE_RANDOM));

        this.iv_cycle.hoverProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue) {
                VideoController.this.iv_cycle.setImage(cycle_icon_black);
            }
            if (!newValue) {
                VideoController.this.iv_cycle.setImage(cycle_icon_white);
            }
        });
        this.iv_cycle.setOnMouseClicked(event -> {
            if (event.getButton().equals(MouseButton.PRIMARY)) {
                log.info("随机播放按钮:{}", "cycle_button");
                VideoController.this.cycletype.set((VideoController.this.cycletype.get() + 1) % 3);
                VideoController.this.iv_cycle.setImage(ICON_WHITE_RANDOM);
            }
        });
    }

    /**
     * 底部上一首按钮
     */
    public void last_button() {

        Image last_white = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_WHITE_LAST));
        Image last_black = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_BLACK_LAST));

        this.iv_last.hoverProperty().addListener(new ChangeListener<Boolean>() {
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                if (newValue) {
                    VideoController.this.iv_last.setImage(last_black);
                }
                if (!newValue) {
                    VideoController.this.iv_last.setImage(last_white);
                }
            }
        });
        this.iv_last.setOnMouseClicked(event -> {
            if (event.getButton().equals(MouseButton.PRIMARY) && VideoController.this.mp != null) {
                VideoController.this.playindex.set((VideoController.this.playindex.get() - 1 + medias.size()) % medias.size());
            }
        });
    }

    /**
     * 底部下一首按钮
     */
    public void next_button() {

        Image next_white = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_WHITE_NEXT));
        Image next_black = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_BLACK_NEXT));

        this.iv_next.hoverProperty().addListener(new ChangeListener<Boolean>() {
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                if (newValue) {
                    VideoController.this.iv_next.setImage(next_black);
                }
                if (!newValue) {
                    VideoController.this.iv_next.setImage(next_white);
                }
            }
        });
        this.iv_next.setOnMouseClicked(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent event) {
                if (event.getButton().equals(MouseButton.PRIMARY) && VideoController.this.mp != null) {
                    if (VideoController.this.cycletype.get() == 0 || VideoController.this.cycletype.get() == 1) {
                        VideoController.this.playindex.set((VideoController.this.playindex.get() + 1) % medias.size());
                    }
                    if (VideoController.this.cycletype.get() == 2) {
                        VideoController.this.playindex.set(VideoController.this.ran.nextInt(VideoController.this.medias.size()));
                    }
                }
            }
        });
    }

    /**
     * 是否静音按钮
     */
    public void vol_mute_button() {

        Image vol_white = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_WHITE_VOL));
        Image vol_black = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_BLACK_VOL));

        Image mute_white = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_WHITE_MUTE));
        Image mute_black = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_BLACK_MUTE));

        this.iv_vol.hoverProperty().addListener(new ChangeListener<Boolean>() {
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                log.info("静音按钮:{}", newValue);
                if (newValue) {
                    if (VideoController.this.iv_vol.getImage().equals(vol_white)) {
                        VideoController.this.iv_vol.setImage(vol_black);
                    } else if (VideoController.this.iv_vol.getImage().equals(mute_white)) {
                        VideoController.this.iv_vol.setImage(mute_black);
                    }
                }

                if (!newValue) {
                    if (VideoController.this.iv_vol.getImage().equals(vol_black)) {
                        VideoController.this.iv_vol.setImage(vol_white);
                    } else if (VideoController.this.iv_vol.getImage().equals(mute_black)) {
                        VideoController.this.iv_vol.setImage(mute_white);
                    }
                }

            }
        });
        this.iv_vol.setOnMouseClicked(event -> {
            log.info("音量按钮:{}", event.getButton().name());
            if (event.getButton().equals(MouseButton.PRIMARY) && VideoController.this.mp != null) {
                if (VideoController.this.mp.isMute()) {
                    VideoController.this.mp.setMute(false);
                    VideoController.this.iv_vol.setImage(vol_black);
                } else {
                    VideoController.this.mp.setMute(true);
                    VideoController.this.iv_vol.setImage(mute_black);
                }
            }
        });
    }

    /**
     * 音量刻度
     */
    public void sl_vol_button() {
        this.sl_vol.setPrefWidth(100.0D);
        this.sl_vol.setValue(sl_vol_num);
    }


    /**
     * 底部播放按钮
     */
    public void play_button() {

        Image play_white = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_WHITE_PLAY));
        Image play_black = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_BLACK_PLAY));

        Image pause_white = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_WHITE_PAUSE));
        Image pause_black = new Image(ImagePath.path(ImagePath.ImagePathType.ICON_BLACK_PAUSE));

        this.iv_play.hoverProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue) {
                if (VideoController.this.isplaying.get()) {
                    VideoController.this.iv_play.setImage(pause_black);
                }

                if (!VideoController.this.isplaying.get()) {
                    VideoController.this.iv_play.setImage(play_black);
                }
            }
            if (!newValue) {
                if (VideoController.this.isplaying.get()) {
                    VideoController.this.iv_play.setImage(pause_white);
                }
                if (!VideoController.this.isplaying.get()) {
                    VideoController.this.iv_play.setImage(play_white);
                }
            }
        });
        this.iv_play.setOnMouseClicked(event -> {
            if (event.getButton().equals(MouseButton.PRIMARY) && VideoController.this.mp != null) {
                VideoController.this.isplaying.set(!VideoController.this.isplaying.get());
                if (VideoController.this.isplaying.get()) {
                    VideoController.this.iv_play.setImage(pause_white);
                } else {
                    VideoController.this.iv_play.setImage(play_white);
                }
            }
        });
        this.isplaying.addListener((observable, oldValue, newValue) -> {
            if (newValue) {
                VideoController.this.iv_play.setImage(pause_white);
                if (VideoController.this.mp.getStatus().equals(MediaPlayer.Status.PAUSED)) {
                    VideoController.this.mp.play();
                } else {
                    VideoController.this.myPlay();
                }
            }
            if (!newValue) {
                VideoController.this.iv_play.setImage(pause_black);
                VideoController.this.mp.pause();
            }
        });
    }

    public void myPlay() {
        this.mp.dispose();
        this.mp = new MediaPlayer(medias.get(this.playindex.get()));
        initProgressBar(mp);
        this.mp.setOnReady(() -> {
            VideoController.this.mp.play();
            VideoController.this.isplaying.set(true);
        });
        this.isplaying.set(true);
        this.sb = new StringBuffer(files.get(this.playindex.get()).getName());
        this.label_name.setText(this.sb.substring(0, this.sb.length() - 4));

        this.mp.setVolume(sl_vol_num);

        this.sl_vol.valueProperty().addListener((observableValue, number, t1) -> {
            log.info("音量调节:{}", t1.doubleValue());
            VideoController.this.mp.setVolume(t1.doubleValue() / 100);
        });

        this.mp.currentTimeProperty().addListener((observable, oldValue, newValue) -> {
            VideoController.this.playprogress.set(newValue.toSeconds() / VideoController.this.mp.getTotalDuration().toSeconds());
            int m1 = (int) newValue.toMinutes();
            int s1 = (int) (newValue.toSeconds() % 60.0D);
            int m2 = (int) VideoController.this.mp.getTotalDuration().toMinutes();
            int s2 = (int) (VideoController.this.mp.getTotalDuration().toSeconds() % 60.0D);
            VideoController.this.label_time.setText(m1 + ":" + s1 + " / " + m2 + ":" + s2);
        });
        this.mp.setAudioSpectrumListener((timestamp, duration, magnitudes, phases) -> {
            for (int i = 0; i < 100; ++i) {
                VideoController.this.getHeight().get(i).set((magnitudes[i] + 60.0F) * 2.0F);
            }
        });
        this.mp.setOnEndOfMedia(() -> {
            if (VideoController.this.cycletype.get() == 0) {
                VideoController.this.playindex.set((VideoController.this.playindex.get() + 1) % medias.size());
            } else if (VideoController.this.cycletype.get() == 1) {
                VideoController.this.playindex.set(VideoController.this.playindex.get());
                VideoController.this.myPlay();
            } else {
                VideoController.this.playindex.set(VideoController.this.playindex.get() + VideoController.this.ran.nextInt(medias.size()) % medias.size());
            }
        });
        this.mv.setMediaPlayer(mp);
    }

    public void initListView() {
        listView.setItems(files);
        Text placehold = new Text("列表为空，点击设置添加音乐目录");
        placehold.setFill(Color.WHITE);
        placehold.setFont(Font.font(19.0D));
        listView.setPlaceholder(placehold);

        listView.setBackground(new Background(new BackgroundFill(Color.TRANSPARENT, null, null)));
        listView.setFixedCellSize(40.0D);
        list_cell();
    }

    private void list_cell() {
        listView.setCellFactory(new Callback<ListView<File>, ListCell<File>>() {
            public ListCell<File> call(ListView<File> param) {
                final ListCell<File> cell = new ListCell<File>() {
                    protected void updateItem(File item, boolean empty) {
                        super.updateItem(item, empty);
                        if (!empty && item != null) {
                            sb = new StringBuffer(item.getName());
                            Text text = new Text(sb.substring(0, sb.length() - 4));
                            text.setStrokeWidth(300);
                            text.setTextAlignment(TextAlignment.CENTER);
                            if (this.getIndex() == VideoController.this.playindex.get()) {
                                text.setFont(Font.font(16.0D));
                                text.setFill(Color.DEEPSKYBLUE);
                            } else {
                                text.setFont(Font.font(13.0D));
                                //text.setFill(Color.WHITE);
                            }

                            this.setAlignment(Pos.CENTER_LEFT);
                            this.setGraphic(text);
                            this.setOpacity(1.0D);
                            this.setBackground(new Background(new BackgroundFill(Color.TRANSPARENT, (CornerRadii) null, (Insets) null)));
                        } else {
                            this.setGraphic(null);
                            this.setOpacity(0.0D);
                        }

                    }
                };
                MenuItem mi1 = new MenuItem("从列表中移除");
                mi1.setOnAction(new EventHandler<ActionEvent>() {
                    public void handle(ActionEvent event) {
                        VideoController.getMusicFiles().remove(cell.getIndex());
                        VideoController.getMusicMedias().remove(cell.getIndex());
                    }
                });
                ContextMenu cm = new ContextMenu(mi1);
                cell.setContextMenu(cm);
                cell.setOnMouseClicked(event -> {
                    if (event.getClickCount() == 2 && event.getButton() == MouseButton.PRIMARY) {
                        VideoController.this.playindex.set(cell.getIndex());
                    }
                });
                VideoController.this.playindex.addListener(new ChangeListener<Number>() {
                    public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                        Text text;
                        if (newValue.intValue() == cell.getIndex()) {
                            if (cell.getGraphic() != null) {
                                text = (Text) cell.getGraphic();
                                text.setFont(Font.font(16.0D));
                                text.setFill(Color.DEEPSKYBLUE);
                            }
                        } else if (cell.getGraphic() != null) {
                            text = (Text) cell.getGraphic();
                            text.setFont(Font.font(13.0D));
                            text.setFill(Color.BLACK);
                        }

                    }
                });
                return cell;
            }
        });

        listView.widthProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observableValue, Number number, Number t1) {
                root_width.setValue(t1.doubleValue());
            }
        });
    }

    private void initProgressBar(MediaPlayer player) {
        progressBar.setCurrentTime(Duration.ZERO);
        progressBar.durationProperty().bind(player.getMedia().durationProperty());
        progressBar.bufferProgressTimeProperty().bind(player.bufferProgressTimeProperty());
        player.currentTimeProperty().addListener((ob1, ov1, nv1) -> {
            progressBar.setCurrentTime(nv1);
        });

        progressBar.setOnMouseDragged(event1 -> {
            if (player.getStatus() == MediaPlayer.Status.PLAYING) {
                player.seek(progressBar.getCurrentTime());
            }
        });

        progressBar.setOnMouseClicked(event1 -> {
            if (player.getStatus() == MediaPlayer.Status.PLAYING) {
                player.seek(progressBar.getCurrentTime());

            }
        });
    }

    public static ObservableList<File> getDirsList() {
        String dir = config_path();
        File file = new File(dir);
        if (file.exists() && file.isDirectory()) {
            dirs.add(file);
        }
        return dirs;
    }

    public static String config_path() {
        Resource resource = new ClassPathResource("video.properties");
        InputStream inputStream = resource.getStream();
        Properties properties = new Properties();
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return properties.getProperty("base.video.path");
    }

    public static ObservableList<Media> getMusicMedias() {
        if (medias.size() == 0) {
            getDirsList().forEach((dir) -> {
                if (dir.exists()) {
                    File[] files = dir.listFiles((dir1, name) -> name.endsWith("mp4"));
                    for (File file : files) {
                        String uri = file.toURI().toASCIIString();
                        Media media = new Media(uri);
                        medias.add(media);
                    }
                }
            });
            return medias;
        } else {
            return medias;
        }
    }

    public static ObservableList<File> getMusicFiles() {
        if (files.size() == 0) {
            getDirsList().forEach((dir) -> {
                if (dir.exists()) {
                    File[] mfiles = dir.listFiles((dir1, name) -> name.endsWith("mp4"));
                    files.addAll(mfiles);
                }
            });
            return files;
        } else {
            return files;
        }
    }

    public static void addDir(File file) {
        File[] addfiles = file.listFiles((dir, name) -> name.endsWith("mp4"));
        files.clear();
        for (int i = 0; i < addfiles.length; ++i) {
            Media media = new Media(addfiles[i].toURI().toASCIIString());
            medias.add(media);
            files.add(addfiles[i]);
        }
    }
}
